package com.example.kotlindemo.modules.network

import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.kotlindemo.utils.ApiClient
import kotlinx.coroutines.launch


class LoginViewModel : ViewModel() {

    private val loginRepository = LoginRepository() // 实际项目中建议通过构造函数注入

    // 使用 MutableLiveData 对内可变，对外暴露为不可变的 LiveData
    private val _loginResult = MutableLiveData<Resource<UserResponse>>()
    val loginResult: LiveData<Resource<UserResponse>> = _loginResult // UI 层观察这个 LiveData

    // --- 协程的用法和特点讲解 (在 ViewModel 中) ---
    // 1. `viewModelScope`:
    //    - 这是 AndroidX lifecycle-viewmodel-ktx 库提供的扩展属性。
    //    - 它是一个绑定到 ViewModel 生命周期的 CoroutineScope。
    //    - 当 ViewModel 被销毁时（通常是关联的 Activity/Fragment 结束后），`viewModelScope` 会自动取消其内部启动的所有协程。这有助于防止内存泄漏和不必要的工作。
    //
    // 2. `launch { ... }`:
    //    - 是一个 Coroutine Builder，用于启动一个新的协程，而不会阻塞当前线程（"fire and forget"）。
    //    - 它返回一个 Job 对象，可以用来手动取消协程，但通常我们依赖 `viewModelScope` 的自动取消。
    //    - `viewModelScope.launch` 默认在主线程（Dispatchers.Main.immediate）启动协程，这对于更新 LiveData（进而更新 UI）是安全的。
    //
    // 3. 调用挂起函数 (`suspend fun`):
    //    - 像 `loginRepository.login(params).collect { ... }` 这样的操作包含挂起函数调用（`collect` 是挂起的）。
    //    - 挂起函数只能在协程或其他挂起函数中调用。`viewModelScope.launch` 提供了一个协程环境。
    //
    // 4. 收集 Flow (`collect`):
    //    - 在 `viewModelScope.launch` 启动的协程中，我们调用 Flow 的 `collect` 方法来接收 Repository 发射的 `Resource` 状态。
    //    - 由于 `collect` 是挂起函数，它会“暂停”协程的执行，直到 Flow 发射一个新值。
    //    - 因为 Repository 中的 `flowOn(Dispatchers.IO)` 确保了网络请求在后台线程，而 `viewModelScope.launch` 默认在主线程，所以 `collect` 代码块（更新 `_loginResult.value`）安全地在主线程执行。

    fun performLogin(params: LoginParams) {
        // 使用 viewModelScope 启动协程，确保与 ViewModel 生命周期绑定
        viewModelScope.launch {
            // 调用 Repository 的 login 函数，它返回一个 Flow
            // 然后使用 collect 收集 Flow 发射的状态
            loginRepository.login(params).collect { resource ->
                // 每次 Flow 发射一个新的 Resource 状态时，更新 LiveData
                _loginResult.value = resource
                // LiveData.setValue() 必须在主线程调用，
                // LiveData.postValue() 可以在后台线程调用，但这里 launch 默认在主线程，所以 setValue 更直接。
            }
        }
    }

    // 在 ViewModel 销毁前保存 Token 的示例 (也可以放在 Repository 或 UseCase 中)
    fun saveToken(context: Context?, token: String?) {
        // 注意：ViewModel 不应直接持有 Context。更好的方式是：
        // 1. 在 Repository 中处理 Token 保存。
        // 2. 或者通过依赖注入传入一个专门的 TokenStorage 服务。
        // 这里为了演示，暂时调用 ApiClient 的静态方法。
        ApiClient.saveTokenToStorage(context?.applicationContext, token)
    }
}